﻿namespace Services.Implement;

/// <summary>
/// 角色服务
/// </summary>
public class RoleBLL(ISqlSugarClient db, IUserBLL userBLL, IFeatureBLL featureBLL) : BaseBLL<Role>(db), IRoleBLL
{
    private readonly ISqlSugarClient _db = db;
    private readonly IUserBLL _userBLL = userBLL;
    private readonly IFeatureBLL _featureBLL = featureBLL;

    /// <summary>
    /// 所有角色
    /// </summary>
    /// <returns></returns>
    public async Task<List<Role>> GetAllAsync(Expression<Func<Role, bool>>? whereExpression = null)
    {
        return await GetListAsync(whereExpression);
    }
    /// <summary>
    /// 角色列表
    /// </summary>
    /// <returns></returns>
    public async Task<Role> GetRoleByIdAsync(int roleid)
    {
        return await GetAsync(x => x.Id == roleid);
    }
    /// <summary>
    /// 获取角色下拉值
    /// </summary>
    /// <returns></returns>
    public async Task<List<Role>> GetDownListAsync()
    {
        return await GetListAsync(x => x.Id != 1 && x.Enable == 1);
    }
    /// <summary>
    /// 获取角色列表
    /// </summary>
    /// <returns></returns>
    public async Task<List<RoleVM>> GetPageListAsync(RolePageQueryRM queryRM)
    {
        var roleList = (await GetListAsync(x => x.Id != 1)).OrderByDescending(x => x.Id).ToList();
        if (!string.IsNullOrWhiteSpace(queryRM.RoleName))
        {
            roleList = roleList.Where(x => x.Name.Contains(queryRM.RoleName)).ToList();
        }
        if (queryRM.Enable != -1)
        {
            roleList = roleList.Where(x => x.Enable == queryRM.Enable).ToList();
        }
        var roleVMs = new List<RoleVM>();
        var allFeatures = await _featureBLL.GetAllAsync();
        var userList = await _userBLL.GetListAsync(x => x.Id != 1 && x.Enable == 1);
        foreach (var role in roleList)
        {
            var roleVM = new RoleVM
            {
                Id = role.Id,
                Name = role.Name,
                UserCount = role.Enable == 1 ? userList.Count(x => x.Roles.Contains(role.Id)) : 0,
                Features = role.Features,
                FeatureNames = GetFeatures(role.Features, allFeatures),
                Enable = role.Enable,
            };
            roleVMs.Add(roleVM);
        }
        if (!string.IsNullOrWhiteSpace(queryRM.FeatureName))
        {
            roleVMs = roleVMs.Where(x => x.FeatureNames.Contains(queryRM.FeatureName)).ToList();
        }
        #region 排序
        queryRM.FieldName = !string.IsNullOrWhiteSpace(queryRM.FieldName) ? queryRM.FieldName.ToLower() : string.Empty;
        if (string.IsNullOrWhiteSpace(queryRM.FieldName))
        {
            roleVMs = roleVMs.OrderByDescending(t => t.Id).ToList();
        }
        else
        {
            if (queryRM.Desc)
            {
                if (queryRM.FieldName == "usercount")
                {
                    roleVMs = roleVMs.OrderByDescending(t => t.UserCount).ToList();
                }
                else if (queryRM.FieldName == "enable")
                {
                    roleVMs = roleVMs.OrderByDescending(t => t.Enable).ToList();
                }
            }
            else
            {
                if (queryRM.FieldName == "usercount")
                {
                    roleVMs = roleVMs.OrderBy(t => t.UserCount).ToList();
                }
                else if (queryRM.FieldName == "enable")
                {
                    roleVMs = roleVMs.OrderBy(t => t.Enable).ToList();
                }
            }
        }
        #endregion
        return roleVMs;
    }
    /// <summary>
    /// 根据角色Id获取功能权限列表
    /// </summary>
    /// <param name="roleId"></param>
    /// <returns></returns>
    public async Task<List<Feature>> GetFeatureListByRoleIdAsync(int roleId)
    {
        var featureIds = new List<int>();
        if (roleId != 1)
        {
            var role = await GetAsync<Role>(x => x.Id == roleId);
            featureIds = role.Features;
        }
        else
        {
            featureIds = (await _featureBLL.GetAllAsync()).Select(x => x.Id).ToList();
        }
        if (!featureIds.Any())
        {
            return new List<Feature>();
        }
        //featureIds = GetAuthFeatureIds(featureIds);
        return (await _featureBLL.GetAllAsync()).Where(x => featureIds.Contains(x.Id)).ToList();
    }


    public async Task<List<Feature>> GetFeatureMenuListByRoleIdAsync(int roleId)
    {
        var featureList = await GetFeatureListByRoleIdAsync(roleId);
        var firstLevelItems = featureList.Where(f => f.Pid == 0).OrderBy(f => f.Order).ToList();
        var featureIds = new List<int>();
        // featureList = featureList.Where(t => t.Type == 2).ToList();
        var featuresList = new List<Feature>();
        if (firstLevelItems.Count == 0)
        {
            return new List<Feature>();
        }
        foreach (var feature in firstLevelItems)
        {
            if (feature.Type == 2)
            {
                featureIds.Add(feature.Id);
            }
            else
            {
                var t = _featureBLL.GetChildIds(feature.Id, featureList);
                featureIds = featureIds.Concat(t).ToList();
            }
        }
        foreach (var featureId in featureIds)
        {
            var feature = featureList.FirstOrDefault(t => t.Id == featureId);
            if (feature != null)
            {
                featuresList.Add(feature);
            }
        }

        return featuresList;
    }

    /// <summary>
    /// 获取功能名称
    /// </summary>
    /// <param name="idList"></param>
    /// <param name="features"></param>
    /// <returns></returns>
    private string GetFeatures(List<int> idList, List<Feature> features)
    {
        var selectedFeatures = features.Where(f => idList.Contains(f.Id)).ToList();
        var featureTrees = _featureBLL.GetFeatureTree(selectedFeatures);
        var sb = new StringBuilder();
        bool first = true;
        foreach (var item in featureTrees)
        {
            if (first)
            {
                first = false;
                sb.Append(item.Name);
            }
            else
            {
                sb.Append($"、 {item.Name}");
            }
            if (item.Children.Any())
            {
                sb.Append("(");
                bool childFirst = true;
                foreach (var child in item.Children)
                {
                    if (childFirst)
                    {
                        childFirst = false;
                        sb.Append(child.Name);
                    }
                    else
                    {
                        sb.Append($"、 {child.Name}");
                    }
                }
                sb.Append(")");
            }
        }
        return sb.ToString();
    }

    public async Task<List<FeatureTree>> GetRoleFeatureTreesAsync(int roleId)
    {
        var allFeatures = await _featureBLL.GetAllAsync();
        var featureIds = new List<int>();
        if (roleId != 1)
        {
            var role = await GetRoleByIdAsync(roleId);
            featureIds = role.Features;
        }
        else
        {
            featureIds = allFeatures.Select(f => f.Id).ToList();
        }
        if (!featureIds.Any())
        {
            return new List<FeatureTree>();
        }
        allFeatures = allFeatures.Where(f => featureIds.Contains(f.Id)).ToList();
        return _featureBLL.GetFeatureTreeMenu(allFeatures);
    }
    /// <summary>
    /// 获取功能树
    /// </summary>
    /// <returns></returns>
    public async Task<List<FeatureTree>> GetFeatureTreesAsync(int roleId)
    {
        var allFeatures = await _featureBLL.GetAllAsync();
        var featureIds = new List<int>();
        if (roleId != 1)
        {
            var role = await GetRoleByIdAsync(roleId);
            featureIds = role.Features;
        }
        else
        {
            featureIds = allFeatures.Select(f => f.Id).ToList();
        }
        if (!featureIds.Any())
        {
            return new List<FeatureTree>();
        }
        allFeatures = allFeatures.Where(f => featureIds.Contains(f.Id)).ToList();
        return _featureBLL.GetFeatureTree(allFeatures);
    }

    /// <summary>
    /// 新增
    /// </summary>
    /// <param name="createRM"></param>
    /// <returns></returns>
    public async Task<ResultModel> AddAsync(RoleCreateRM createRM)
    {
        var resultModel = new ResultModel();
        // 名称查重
        Role nameRepeatedItem = await GetAsync(x => x.Name == createRM.Name);
        if (nameRepeatedItem != null)
        {
            resultModel.code = -2;
            resultModel.msg = "角色名称已存在";
            return resultModel;
        }

        Role role = new Role
        {
            Name = createRM.Name,
            Features = createRM.FeatureIdList,
            Enable = createRM.Enable,
        };
        resultModel.data = await InsertAsync(role);
        resultModel.code = 1;
        return resultModel;
    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="updateRM"></param>
    /// <returns></returns>
    public async Task<ResultModel> UpdateAsync(RoleUpdateRM updateRM)
    {
        if (updateRM.Id == 1)
        {
            throw new Exception("超级管理员角色不允许修改");
        }

        var resultModel = new ResultModel();
        var role = await GetRoleByIdAsync(updateRM.Id);
        if (role == null)
        {
            throw new Exception("更新对象不存在");
        }

        // 名称查重
        if (updateRM.Name != role.Name)
        {
            var nameRepeatedItem = await GetAsync(x => x.Name == updateRM.Name);
            if (nameRepeatedItem != null)
            {
                resultModel.code = -2;
                resultModel.msg = "角色名称已存在";
                return resultModel;
            }
        }

        // 更新
        role.Features = updateRM.FeatureIdList;
        role.Enable = updateRM.Enable;
        role.Name = updateRM.Name;
        resultModel.data = await UpdateAsync(role);
        resultModel.code = 1;
        return resultModel;
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id"></param>
    public async Task<string> DeleteByIdAsync(int id)
    {
        var user = await _userBLL.GetAsync(x => SqlFunc.JsonArrayAny(x.Roles, id) && x.Id != 1);
        if (user != null)
        {
            return "R_INUSED";
        }
        var role = await GetRoleByIdAsync(id);
        if (role == null)
        {
            return "R_NOTEXIST";
        }
        await DeleteAsync(role);
        return role.Name;
    }

    /// <summary>
    /// 设置角色状态
    /// </summary>
    /// <param name="rm"></param>
    public async Task<ResultModel> SetRoleEnableByIdsAsync(SetEnableRM rm)
    {
        var ret = new ResultModel();
        if (rm.Ids == null || !rm.Ids.Any())
        {
            ret.code = -1;
            ret.msg = "参数异常！";
            return ret;
        }
        var roleList = await GetListAsync(x => rm.Ids.Contains(x.Id));
        if (roleList == null || !roleList.Any())
        {
            ret.code = -1;
            ret.msg = "未获取到角色！";
            return ret;
        }
        roleList.ForEach(x => { x.Enable = rm.Enable; });
        var res = await UpdateAsync(roleList);
        ret.data = res;
        ret.code = res ? 1 : -1;
        return ret;
    }

    /// <summary>
    /// 查询已授权用户
    /// </summary>
    /// <returns></returns>
    public async Task<List<SelectedUserVM>> GetAssociatedUserByRoleIdAsync(int roleId)
    {
        var selectedUserIds = new List<SelectedUserVM>();
        var role = await GetAsync<Role>(roleId);
        if (role == null || role.Enable == 2)
        {
            return selectedUserIds;
        }

        var userlist = await _userBLL.GetListAsync(x => SqlFunc.JsonArrayAny(x.Roles, role.Id) && x.Id != 1);
        if (userlist != null && userlist.Any())
        {
            var selectUsers = MapperHelper.MapperList<SelectedUserVM, User>(userlist);
            selectedUserIds = selectUsers;
        }
        return selectedUserIds;
    }

    /// <summary>
    /// 获取角色详情
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<RoleDetailVM> GetDetail(int id)
    {
        var role = await GetAsync(x => x.Id == id);
        var allFeatures = await _featureBLL.GetAllAsync();
        var detailVM = new RoleDetailVM
        {
            Id = role.Id,
            Name = role.Name,
            Enable = role.Enable,
        };

        detailVM.SelectedFeatureIds = role.Features;

        return detailVM;
    }
    /// <summary>
    /// 关联用户
    /// </summary>
    /// <param name="updateRM"></param>
    /// <returns></returns>
    public async Task<ResultModel> BindUser(BindUserRM updateRM)
    {
        var resultModel = new ResultModel();
        var result = await _db.Ado.UseTranAsync(async () =>
        {
            var role = await GetAsync(x => x.Id == updateRM.RoleId);
            if (role == null)
            {
                throw new Exception("角色不存在");
            }
            var users = await _userBLL.GetListAsync(x => SqlFunc.JsonArrayAny(x.Roles, role.Id) && x.Id != 1);
            if (users != null && users.Any())
            {
                foreach (var item in users)
                {
                    if (item.Roles.Contains(role.Id))
                    {
                        item.Roles.Remove(role.Id);
                    }
                    if (item.RoleId == role.Id)
                    {
                        item.RoleId = 0;
                    }
                }
                await _userBLL.UpdateAsync(users);
            }
            var insertUsers = new List<User>();
            foreach (var item in updateRM.UserIds)
            {
                var user = await _userBLL.GetAsync(x => x.Id == item);
                if (user == null) continue;
                if (!user.Roles.Contains(role.Id))
                {
                    user.Roles.Add(role.Id);
                }
                if (user.RoleId == 0)
                {
                    user.RoleId = updateRM.RoleId;
                }
                insertUsers.Add(user);
            }
            await _userBLL.UpdateAsync(insertUsers);
            resultModel.msg = "关联用户成功！";
        });

        if (result.Data == false) //业务的返回值 
        {
            if (result.IsSuccess == true)//事务提交完成
                resultModel.code = 1;
            else//事务执行了回滚
                resultModel.code = -1;
            throw result.ErrorException;
        }
        else
        {
            resultModel.code = 1;
            return resultModel;
        }
    }
}
